/**
 * 
 * Author : iamluodong@126.com
 */
var program = require('commander');
var cluster = require('cluster');
var http = require("http")
var speedLimit = require("./speedLimit")

var stats = {};


function _master() {
    program
        .version('0.1.1')
        .usage('[options] <url>')
        .option('-c, --concurrent [n]', '并发数', 50, parseInt)
        .option('-w, --worker [n]', '工作进程数,默认1', 2, parseInt)
        .option('-b, --bitrate [n]', '速速率(Kbit/s) 0 不限速', 500, parseInt)
        .parse(process.argv);

    program.url = process.argv[process.argv.length - 1]
    if (program.url.indexOf("http") != 0) {
        console.log("缺少测试URL!");
        program.help();
        return;
    }

    // Fork workers.
    for (var i = 0; i < program.worker; i++) {
        cluster.fork();
    }
    function messageHandler(msg) {
        stats[msg.id] = msg.taskResult;
    }
    for (var x in cluster.workers) {
        cluster.workers[x].on('message', messageHandler);
        stats[cluster.workers[x].id] = { totaldownload: 0, speed: 0, alive: 0 };
        cluster.workers[x].send({ cmd: "start", id: cluster.workers[x].id, url: program.url, concurrent: program.concurrent, bitrate: program.bitrate });
    }

    cluster.on('exit', function (worker, code, signal) {
        stats[worker.id].end = true;
        // delete stats[worker.id];
        //console.log('worker ' + worker.process.pid + 'died');
    });

    require("./output").start(stats);

}

function _worker() {
    var taskResult = { alive: 0, ok: 0, err: 0, totaldownload: 0, starttime: 0 };

    function download(url, bitrate, callback) {

        var request = http.get(url, function (res) {
            //console.log(url, bitrate);
            if (res.statusCode != 200 && res.statusCode != 201) {
                callback(new Error("response error" + res.statusCode))
                return;
            }
            //kb ==> Byte
            if (bitrate > 0) {
                var sl = new speedLimit(bitrate / 8 * 1024);
                res.pipe(sl);

                sl.on("data", function (data) {
                    taskResult.totaldownload += data.length;
                })
            } else {
                res.on("data", function (data) {
                    taskResult.totaldownload += data.length;
                })
            }
            res.on("end", function () {
                callback()
            })

        })
        request.on('error', function (error) {
            callback("onerror");
        })
        request.on('socket', function (socket) {
            socket.on('error', function (err) {
                // console.log("onsocketdfddf")
                //callback("onerror");
            })

        })
    }

    function callback(err) {
        taskResult.alive--;
        // console.log(taskResult)
        if (err)
            taskResult.err++;
        else
            taskResult.ok++;


    }
    function messageHandler(msg) {
        // log(msg)
        switch (msg.cmd) {
            case "start":
                taskResult.starttime = new Date().getTime();
                taskResult.alive = msg.concurrent;
                for (var i = 0; i < msg.concurrent; i++) {
                    download(msg.url, msg.bitrate, callback);
                }
                setInterval(function () {
                    var ltime = new Date().getTime() - taskResult.starttime;
                    taskResult.speed = parseInt(taskResult.totaldownload / ltime * 1000)
                    process.send({ cmd: "report", id: msg.id, taskResult: taskResult });
                    if (taskResult.alive == 0) {
                        process.exit(0)
                    }
                }, 1000)
        }
    }
    process.on('message', messageHandler);

}

if (cluster.isMaster)
    _master();
else
    _worker();